#!/bin/sh

validate_integer() {
    case "$1" in
        ''|0|*[!0-9]*) return 1 ;; 
        [1-9]*) return 0 ;;
        *) return 1 ;;
    esac
}

# validate ipv4 address format
validate_ipv4() {
    echo "$1" | awk -F. '
    BEGIN { valid = 0 }
    NF == 4 {
        valid = 1
        for (i=1; i<=4; i++) {
            if ($i !~ /^[0-9]{1,3}$/ || $i < 0 || $i > 255 || (length($i)>1 && substr($i,1,1)=="0")) {
                valid = 0
                exit
            }
        }
    }
    END { exit !valid }'
    return $?
}

# validate ipv4/cidr address format
validate_cidr() {
    cidr="$1"
    stat=1
    if echo "$cidr" | grep -Eq '^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}/[0-9]{1,2}$'; then
        ip=$(echo "$cidr" | cut -d'/' -f1)
        mask=$(echo "$cidr" | cut -d'/' -f2)
        if validate_ipv4 "$ip" && [ "$mask" -ge 0 ] && [ "$mask" -le 32 ] 2>/dev/null; then
            stat=0
        fi
    fi
    return "$stat"
}

# Get all physical network interfaces (excluding virtual interfaces)
get_interfaces() {
    ls /sys/class/net | grep -Ev '^(lo)'
}

# Display current interface status
show_status() {
    printf "\nCurrent network interface status:\n"
    # Print table header
    echo "INTERFACE   MAC_ADDRESS         IP_ADDRESS          STATUS"
    echo "----------------------------------------------------------------"
    ip link show | awk -F': ' '/^[0-9]+:/ && $2 != "lo" {print $2}' | while read iface; do
        # Get MAC address
        mac=$(ip link show dev "$iface" | awk '/link\/ether/ {print $2}')
        # Get IPv4 address (skip IPv6)
        ip=$(ip addr show dev "$iface" | awk '/inet / {print $2}')
        # Extract status (UP/DOWN) - improved to avoid duplicates
        state=$(ip link show dev "$iface" | awk '{
            for (i=2; i<=NF; i++) {
                if ($i ~ /<.*>/) {
                    if ($i ~ /UP/) {print "UP"; exit}
                    else if ($i ~ /DOWN/) {print "DOWN"; exit}
                }
            }
        }')
        # Print formatted output (one line per interface)
        printf "%-10s  %-18s  %-18s  %s\n" "$iface" "$mac" "$ip" "$state"
    done
    echo "----------------------------------------------------------------"
}

# DHCP activation function
dhcp_activate() {
    local iface=$1
    printf "\nActivating $iface via DHCP\n"
    
    ip link set "$iface" up
    udhcpc -i "$iface" -s /scripts/dhcpc
    
    if [ $? -eq 0 ]; then
        printf "\nDHCP configuration successful!\n"
        ip addr show "$iface" | awk '/inet / {print $2}'
    else
        printf "\nDHCP configuration failed!\n"
        activate_menu
    fi
}

# Static IP activation function
static_activate() {
    local iface=$1
    printf "\nConfiguring static IP for $iface\n"
    read -p "Input IP address/CIDR (e.g., 192.168.1.100/24): " ip_cidr
    while true; do
        if validate_cidr "$ip_cidr"; then
            break
        else
            read -p "Invalid input, Re-Input IP address/CIDR (e.g., 192.168.1.100/24): " ip_cidr
        fi
    done

    read -p "Enter gateway (leave blank to skip): " gateway
    while true; do
        if [ -z "$gateway" ] || validate_ipv4 "$gateway"; then
            break
        else
            read -p "Invalid input, Re-Input gateway (leave blank to skip): " gateway
        fi
    done

    printf "\nApplying configuration..."
    ip addr add "$ip_cidr" dev "$iface"
    ip link set "$iface" up
    
    [ -n "$gateway" ] && {
        ip route add default via "$gateway" dev "$iface"
        echo "Default gateway set to: $gateway"
    }
    
    printf "\nCurrent configuration:"
    ip addr show "$iface" | awk '/inet / {print $2}'
    ip route show | grep default
}

# Interface activation method menu
activate_menu() {
    local iface=$1
    printf "Interface: $iface\n"
    echo "Select activation method:"
    echo "1) DHCP (automatic configuration)"
    echo "2) Static IP (manual configuration)"
    echo "3) Go back"

    read -p "Select choice [1-3]: " choice
    while true; do
        if validate_integer "$choice"; then
            break
        else
            read -p "Invalid Select,Re-Select choice [1-3]: " choice
        fi
    done
    case $choice in
        1) dhcp_activate "$iface" ;;
        2) static_activate "$iface" ;;
        3) interface_menu ;;
        *) echo "Invalid Select"; sleep 1; activate_menu "$iface" ;;
    esac
}

# Interface selection menu
interface_menu() {
    show_status
    printf "\nAvailable physical interfaces:\n"
    interfaces=$(get_interfaces)
    count=1
    for iface in $interfaces; do
        echo "$count) $iface"
        count=$((count+1))
    done

    read -p "Select interface number: " num
    while true; do
        if validate_integer "$num"; then
            break
        else
            read -p "Invalid Select,Re-Select interface number: " num
        fi
    done

    if [ "$num" -gt 0 ]; then
        selected_if=$(echo "$interfaces" | awk -v n="$num" '{if(NR==n) print $0}')
        if [ -n "$selected_if" ]; then
            activate_menu "$selected_if"
        else
            echo "Invalid Select"; sleep 1; interface_menu
        fi
    else
        echo "Invalid Select"; sleep 1; interface_menu
    fi
}

# Start the interface menu
interface_menu